package com.squareup.picasso;

import static com.squareup.picasso.RequestHandler.calculateInSampleSize;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;

import com.squareup.picasso.Picasso.LoadedFrom;

import java.io.IOException;
import java.io.InputStream;

final class MediaStoreRequestHandler extends ContentStreamRequestHandler {
    enum PicassoKind {
        MICRO(3, 96, 96),
        MINI(1, 512, 384),
        FULL(2, -1, -1);

        final int androidKind;
        final int height;
        final int width;

        private PicassoKind(int androidKind, int width, int height) {
            this.androidKind = androidKind;
            this.width = width;
            this.height = height;
        }
    }


    private static final String[] CONTENT_ORIENTATION = new String[]{"orientation"};

    MediaStoreRequestHandler(Context context) {
        super(context);
    }

    private static int getExifOrientation(ContentResolver contentResolver, Uri uri) {
        Cursor cursor = null;
        try {
            cursor = contentResolver.query(uri, MediaStoreRequestHandler.CONTENT_ORIENTATION, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                return cursor.getInt(0);
            }
        } catch (RuntimeException runtimeException) {

        } finally {
            if (cursor != null) {
                try {
                    cursor.close();
                } catch (Exception e) {

                }
            }
        }
        return 0;
    }

    public final boolean canHandleRequest(Request result) {
        Uri uri = result.uri;
        return "content".equals(uri.getScheme()) && "media".equals(uri.getAuthority());
    }

    public final Result load(Request request) throws IOException {
        ContentResolver contentResolver = this.context.getContentResolver();
        int exifOrientation = MediaStoreRequestHandler.getExifOrientation(contentResolver, request.uri);
        String mimeType = contentResolver.getType(request.uri);
        int isVideo = mimeType == null || !mimeType.startsWith("video/") ? 0 : 1;
        if (request.hasSize()) {
            int targetWidth = request.targetWidth;
            int targetHeight = request.targetHeight;
            PicassoKind picassoKind;
            if (targetWidth > PicassoKind.MICRO.width || targetHeight > PicassoKind.MICRO.height) {
                if (targetWidth <= PicassoKind.MINI.width && targetHeight <= PicassoKind.MINI.height) {
                    picassoKind = PicassoKind.MINI;
                } else {
                    picassoKind = PicassoKind.FULL;
                }
            } else {
                picassoKind = PicassoKind.MICRO;
            }

            if (isVideo == 0 && picassoKind == PicassoKind.FULL) {
                return new Result(null, this.getSource(request), LoadedFrom.DISK, exifOrientation);
            }

            long id = ContentUris.parseId(request.uri);
            BitmapFactory.Options options = createBitmapOptions(request);
            options.inJustDecodeBounds = true;
            calculateInSampleSize(request.targetWidth, request.targetHeight, picassoKind.width, picassoKind.height, options, request);
            Bitmap bitmap;
            if (isVideo != 0) {
                int kind = 1;
                if (picassoKind != PicassoKind.FULL) {
                    kind = picassoKind.androidKind;
                }
                bitmap = MediaStore.Video.Thumbnails.getThumbnail(contentResolver, id, kind, options);
            } else {
                bitmap = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id, picassoKind.androidKind, options);
            }

            if (bitmap == null) {
                return new Result(null, this.getSource(request), LoadedFrom.DISK, exifOrientation);
            } else {
                return new Result(bitmap, ((InputStream) null), LoadedFrom.DISK, exifOrientation);
            }
        } else {
            return new Result(null, this.getSource(request), LoadedFrom.DISK, exifOrientation);
        }
    }
}

